home *** CD-ROM | disk | FTP | other *** search
- /* Main-level network program:
- * initialization
- * keyboard processing
- * generic user commands
- *
- * Copyright 1991 Phil Karn, KA9Q
- */
- #include <stdio.h>
- #include <time.h>
- #if defined(__TURBOC__) && defined(MSDOS)
- #include <fcntl.h>
- #include <dos.h>
- #include <io.h>
- #include <conio.h>
- #include <ctype.h>
- #include <dir.h>
- #endif
- #ifdef UNIX
- #include <fcntl.h>
- #endif
- #include "global.h"
- #include "config.h"
- #ifdef ANSIPROTO
- #include <stdarg.h>
- #endif
- #include "mbuf.h"
- #include "timer.h"
- #include "proc.h"
- #include "iface.h"
- #include "ip.h"
- #include "tcp.h"
- #include "udp.h"
- #include "ax25.h"
- #include "kiss.h"
- #ifdef ETHER
- #include "enet.h"
- #endif
- #include "netrom.h"
- #include "ftpcli.h"
- #include "telnet.h"
- #include "tty.h"
- #include "session.h"
- #include "hardware.h"
- #include "usock.h"
- #include "socket.h"
- #ifdef LZW
- #include "lzw.h"
- #endif
- #include "cmdparse.h"
- #include "commands.h"
- #include "daemon.h"
- #include "devparam.h"
- #include "domain.h"
- #include "files.h"
- #include "main.h"
- #include "mailbox.h"
- #include "remote.h"
- #include "trace.h"
- #ifdef fprintf
- #undef fprintf
- #endif
- #include "mailutil.h"
- #include "smtp.h"
- #include "version.h"
-
- #undef BETA 1
- #ifdef BSAHAX
- #define BETA 1
- #endif
-
- #ifdef XSPAWN
- #include "xspawn.h"
- #endif
-
- #ifndef UNIX
- /* The following is from the Borland Runtime Library Version 3.0 :
- * Copyright (c) 1987, 1990 by Borland International
- */
- typedef struct
- {
- unsigned char windowx1;
- unsigned char windowy1;
- unsigned char windowx2;
- unsigned char windowy2;
- unsigned char attribute;
- unsigned char normattr;
- unsigned char currmode;
- unsigned char screenheight;
- unsigned char screenwidth;
- unsigned char graphicsmode;
- unsigned char snow;
- union {
- char far * p;
- struct { unsigned off,seg; } u;
- } displayptr;
- } VIDEOREC;
- extern VIDEOREC _video;
- #endif
-
- extern struct cmds DFAR Cmds[],DFAR Startcmds[],DFAR Stopcmds[],Attab[];
-
- #if (!defined(MSDOS) || defined(ESCAPE)) /* PC uses F-10 key always */
- static char Escape = 0x1d; /* default escape character is ^] */
- #endif
-
- #ifdef __TURBOC__
- int dofstat __ARGS((void));
- #endif
- static char Prompt[] = "net> ";
- char NoRead[] = "Can't read %s: %s\n";
- char Badhost[] = "Unknown host %s\n";
- char Badinterface[] = "Interface \"%s\" unknown\n";
- char Existingiface[] = "Interface %s already exists\n";
- char Nospace[] = "No space!!\n"; /* Generic malloc fail message */
- char Nosversion[] = "KA9Q NOS version %s\n";
- #ifdef MSDOS
- char NosLoadInfo[] = "NOS load info: CS=0x%04x DS=0x%04x";
- #endif
- char Noperm[] = "Permission denied.\n";
- char Nosock[] = "Can't create socket\n";
- char SysopBusy[] = "The sysop is busy. Try again later.\n";
- char *Hostname;
- char *Motd; /* Message Of The Day */
- int Attended = TRUE; /* default to attended mode */
- int ThirdParty = TRUE; /* Allows 3rd party mail by default */
- int main_exit; /* from main program (flag) */
- int DosPrompt; /* Use a dos-like prompt */
- int Mprunning; /* flag for other parts (domain) to signal
- * that we are fully configured running.
- */
- struct proc *Cmdpp;
- #ifndef UNIX
- struct proc *Display;
- #endif
- #ifdef LZW
- int Lzwmode = LZWCOMPACT;
- int16 Lzwbits = LZWBITS;
- #endif
-
- #ifdef TRACE
- int Tracesession = 1;
- struct session *Trace = NULLSESSION;
- #endif
-
- static char *DumpAddr = NULL; /* Memory dump pointer */
- static FILE *Logfp;
- time_t StartTime; /* Time that NOS was started */
- static int Verbose;
-
- static void ctohex __ARGS((char *buf,int16 c));
- static void fmtline __ARGS((int16 addr,char *buf,int16 len));
- extern void assign_filenames __ARGS((char *));
- static void logcmd __ARGS((char *));
- #if 0
- void status();
- #endif
-
- int Numrows,Numcols; /* screen size at startup - WG7J */
- struct hist *Histry; /* command recall stuff */
- int Histrysize;
- int Maxhistory = 10;
-
- #ifdef UNIX
- static char **origargv;
- #endif
-
- int
- #ifdef PROTOTYPES
- main(int argc, char **argv)
- #else
- main(argc,argv)
- int argc;
- char *argv[];
- #endif
- {
- char *inbuf,*intmp;
- FILE *fp;
- struct daemon *tp;
- struct mbuf *bp;
- int c;
- #ifdef UNIX
- int no_itimer, did_init;
- char *trace_sm = 0;
- char *def_sm = 0;
- static int oops;
- #else
- struct text_info ti;
- #endif
- struct cur_dirs dirs;
-
- #ifdef UNIX
- if (oops++)
- {
- iostop();
- fprintf(stderr, "NOS PANIC: NOS main re-entered.\n");
- fflush(stderr);
- fflush(stdout);
- kill(getpid(), 11);
- }
- origargv = argv;
- #endif
- #ifdef XSPAWN
- /* These vectors WILL be intercepted by NOS in COMMAND.ASM
- Go ahead and tell XSPAWN to save their current state, now.
- Vector 0x23 is also used by NOS, but is ALREADY being preserved
- by the XSPAWN routines */
- addvect (8, CURRENT);
- addvect (0x10, CURRENT);
- addvect (0x13, CURRENT);
- addvect (0x1b, CURRENT);
- addvect (0x21, CURRENT);
- addvect (0x24, CURRENT);
- addvect (0x28, CURRENT);
- #endif
-
- setversion();
- StartTime = time(&StartTime); /* NOS Start_Up time */
- #ifdef UNIX
- SRANDOM((getpid() << 16) ^ time((long *) 0));
- #else
- randomize();
- #endif
-
- #ifdef UNIX
- no_itimer = 0;
- #else
- /* Borland's library calls int10. Some vga mode utilities do not
- * report the screen sizes correctly into the internal _video structure.
- * This can cause the screen size to be faulty in the gettextinfo call.
- * Instead, read the BIOS data area to get the correct screen info,
- * and update the _video structure for later calls to
- * gettextinfo(), clrscr(), etc... - WG7J
- *
- * If this doesn't work, you can now overwrite the values with
- * the -r and -c command line options - WG7J
- */
- Numrows = (int) *(char far *)MK_FP(0x40,0x84) + 1;
- gettextinfo(&ti);
- Numcols = ti.screenwidth;
- /*
- Numrows = ti.screenheight;
- */
-
- if(Numrows == 1)
- Numrows = 25;
- #endif
-
- #ifdef UNIX
- did_init = 0;
- while((c = getopt(argc,argv,"s:d:x:f:nbvDS:T:")) != EOF){
- #else
- while((c = getopt(argc,argv,"s:d:r:c:x:f:nbvD")) != EOF){
- #endif
- switch(c){
- #ifdef TRACE
- case 'n':
- Tracesession = 0; /* No session for tracing */
- break;
- #endif
- #ifndef UNIX
- case 'r': /* Number of rows on screen */
- Numrows = atoi(optarg);
- break;
- case 'c': /* Number of columns on screen */
- Numcols = atoi(optarg);
- break;
- #endif
- case 's': /* Number of sockets */
- Nusock = atoi(optarg);
- break;
- #ifdef XSPAWN
- case 'x': /* Path for XSWAP temp file */
- _swappath = strdup(optarg);
- break;
- #endif
- #if defined(MSDOS) || defined(UNIX)
- case 'f':
- assign_filenames(optarg);
- #ifdef UNIX
- did_init = 1;
- #endif
- break;
- #endif
- case 'd': /* Root directory for various files */
- initroot(optarg);
- break;
- #ifdef __TURBOC__
- case 'b': /* Use BIOS for screen output */
- directvideo = 0;
- break;
- #endif
- case 'v':
- Verbose = 1;
- break;
- #ifdef UNIX
- case 'D':
- no_itimer = 1; /* for debugging */
- break;
- case 'S':
- if (sm_lookup(optarg, 0))
- def_sm = optarg;
- else
- printf("No session manager \"%s\", using default\n", optarg);
- break;
- case 'T':
- if (sm_lookup(optarg, 0))
- trace_sm = optarg;
- else
- printf("Session manager for trace not found, using default\n");
- break;
- #endif
- }
- }
- #ifdef UNIX
- if (!did_init)
- assign_filenames(".nosrc");
- #endif
-
- #ifndef UNIX
- /* Set the internal structure, in case there was a command
- * line overwrite - WG7J
- */
- _video.screenheight = (unsigned char)Numrows;
- _video.windowx2 = (unsigned char)(Numcols - 1);
- _video.windowy2 = (unsigned char)(Numrows - 1);
- #endif
-
- kinit();
- ipinit();
- #ifdef UNIX
- ioinit(no_itimer);
- #else
- ioinit();
- #endif
- sockinit();
- Cmdpp = mainproc("cmdintrp");
-
- Sessions = (struct session *)callocw(Nsessions,sizeof(struct session));
- #ifdef TRACE
- if(Tracesession)
- #ifdef UNIX
- {
- if (!trace_sm)
- trace_sm = Trace_sessmgr;
- Trace = sm_newsession(trace_sm, NULLCHAR, TRACESESSION, 0);
- }
- #else
- Trace = newsession(NULLCHAR,TRACESESSION,0);
- #endif
- #endif
- #ifdef UNIX
- if (!def_sm)
- def_sm = Command_sessmgr;
- Command = Lastcurr = sm_newsession(def_sm, NULLCHAR, COMMAND, 0);
- #else
- Command = Lastcurr = newsession(NULLCHAR,COMMAND,0);
- #endif
- /* Flow mode is set AFTER we've read the autoexec file !
- * this keeps systems from locking up if the reboot is unattended - WG7J
- */
- #ifndef UNIX
- Display = newproc("display",250,display,0,NULLCHAR,NULL,0);
- #endif
- tprintf(Nosversion,Version);
- tputs(Version2);
- tputs("Copyright 1991 by Phil Karn (KA9Q) and contributors.\n");
- #ifdef BETA
- tputs("This is a BETA version; be warned !\n");
- #endif
-
- rflush();
-
- /* Start background Daemons */
- for(tp=Daemons;;tp++){
- if(tp->name == NULLCHAR)
- break;
- newproc(tp->name,tp->stksize,tp->fp,0,NULLCHAR,NULL,0);
- }
-
- init_dirs(&dirs);
- Command->curdirs=&dirs;
-
- if(optind < argc){
- /* Read startup file named on command line */
- if((fp = fopen(argv[optind],READ_TEXT)) == NULLFILE)
- tprintf(NoRead,argv[optind],sys_errlist[errno]);
- } else {
- /* Read default startup file named in files.c (autoexec.nos) */
- if((fp = fopen(Startup,READ_TEXT)) == NULLFILE)
- tprintf(NoRead,Startup,sys_errlist[errno]);
- }
- if(fp != NULLFILE){
- inbuf = mallocw(BUFSIZ);
- intmp = mallocw(BUFSIZ);
- while(fgets(inbuf,BUFSIZ,fp) != NULLCHAR){
- strcpy(intmp,inbuf);
- if(Verbose){
- tprintf("%s",intmp);
- rflush();
- }
- if(cmdparse(Cmds,inbuf,NULL) != 0){
- tprintf("input line: %s",intmp);
- rflush();
- }
- }
- fclose(fp);
- free(inbuf);
- free(intmp);
- }
-
- Mprunning = 1; /* we are on speed now */
- Command->flowmode = 1; /* set 'more' paging on command screen */
-
- /* Now loop forever, processing commands */
- for(;;){
- if(DosPrompt)
- tprintf("%s ",dirs.dir);
- tputs(Prompt);
- usflush(Command->output);
- if(recv_mbuf(Command->input,&bp,0,NULLCHAR,0) != -1){
- logcmd(bp->data);
- (void)cmdparse(Cmds,bp->data,Lastcurr);
- free_p(bp);
- }
- }
- }
- /* Keyboard input process */
- /* Modified to support F-key session switching,
- * from the WNOS3 sources - WG7J
- */
- void
- keyboard(i,v1,v2)
- int i;
- void *v1;
- void *v2;
- {
- int c;
- struct mbuf *bp;
- register int j,k;
- struct session *sp;
-
- /* Keyboard process loop */
- for(;;){
- c = kbread();
- #if (!defined(MSDOS) || defined(ESCAPE))
- if(c == Escape && Escape != 0)
- c = -2;
- #endif
- if(c == -2 && Current != Command){
- /* Save current tty mode and set cooked */
- swapscreen(Current,Command);
- Lastcurr = Current;
- Current = Command;
- /* set 'more' paging on command screen */
- Command->flowmode = 1;
- }
- if((c < -2) && (c > -12)) { /* F1 to F9 pressed */
- #ifdef TRACE
- /* If F9 is pressed, -11 is returned and we swap to Trace - WG7J */
- if(c == -11) {
- if(Tracesession) {
- if(Current != Trace){
- /* Save current tty mode and set cooked */
- swapscreen(Current,Trace);
- Lastcurr = Current;
- Current = Trace;
- /* turn off 'more' paging on trace screen */
- Trace->flowmode = 0;
- } else {
- /* Toggle back to previous session */
- swapscreen(Trace,Lastcurr);
- Current = Lastcurr;
- Lastcurr = Trace;
- }
- }
- } else {
- #endif
- k = (-1 * c) - 2;
- for(sp = Sessions, j = 0; sp < &Sessions[Nsessions]; sp++) {
- if(sp->type == COMMAND)
- continue;
- j++;
- if(sp->type != FREE && j == k) {
- swapscreen(Current,sp);
- Lastcurr = Current;
- Current = sp;
- break;
- }
- }
- #ifdef TRACE
- }
- #endif
- }
-
- Current->row = Numrows;
- psignal(&Current->row,1);
- if(c >= 0){
- #ifdef UNIX
- if (Current->morewait) /* end display pause, if any */
- Current->morewait = 2;
- #endif
- /* If the screen driver was in morewait state, this char
- * has woken him up. Toss it so it doesn't also get taken
- * as normal input. If the char was a command escape,
- * however, it will be accepted; this gives the user
- * a way out of lengthy output.
- */
- if(!Current->morewait
- && (bp = ttydriv(Current,c)) != NULLBUF){
- send_mbuf(Current->input,bp,0,NULLCHAR,0);
- }
- }
- }
- }
-
- extern int Kblocked;
- extern char *Kbpasswd;
- #ifdef LOCK
-
- /*Lock the keyboard*/
- int
- dolock(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
-
- extern char Noperm[];
-
- /*allow only keyboard users to access the lock command*/
- if(Curproc->input != Command->input) {
- tputs(Noperm);
- return 0;
- }
- if(argc == 1) {
- if(Kbpasswd == NULLCHAR)
- tputs("Set password first\n");
- else {
- Kblocked = 1;
- tputs("Keyboard locked\n");
- Command->ttystate.echo = 0; /* Turn input echoing off! */
- }
- return 0;
- }
- if(argc == 3) {
- if(*argv[1] == 'p') { /*set the password*/
- if(Kbpasswd != NULLCHAR){
- free(Kbpasswd);
- Kbpasswd = NULLCHAR; /* reset the pointer */
- }
- if(!strlen(argv[2]))
- return 0; /* clearing the buffer */
- Kbpasswd = strdup(argv[2]);
- return 0;
- }
- }
-
- tputs("Usage: lock password \"<unlock password>\"\n"
- "or 'lock' to lock the keyboard\n");
-
- return 0;
- }
-
- #endif
-
- #ifdef ALLCMD
- /* Standard commands called from main */
- int
- dodelete(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- int i;
- char fname[128];
-
- for(i=1;i < argc; i++){
- strcpy(fname,make_fname(Command->curdirs->dir,argv[i]));
- if(unlink(fname) == -1){
- tprintf("Can't delete %s: %s\n",fname,sys_errlist[errno]);
- }
- }
- return 0;
- }
- int
- dorename(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- char fname1[128];
- char fname2[128];
-
- strcpy(fname1,make_fname(Command->curdirs->dir,argv[1]));
- strcpy(fname2,make_fname(Command->curdirs->dir,argv[2]));
- if(rename(fname1,fname2) == -1)
- tprintf("Can't rename: %s\n",sys_errlist[errno]);
- return 0;
- }
- int
- docopy(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- FILE *old, *new;
- int ch;
- unsigned char count;
- char fname[128];
-
- strcpy(fname,make_fname(Command->curdirs->dir,argv[1]));
- if((old = fopen(fname,"rb")) == NULL) {
- tprintf("Can't open %s: %s\n",fname,sys_errlist[errno]);
- return 1;
- }
- strcpy(fname,make_fname(Command->curdirs->dir,argv[2]));
- if((new = fopen(fname,"wb")) == NULL) {
- tprintf("Can't open %s: %s\n",fname,sys_errlist[errno]);
- fclose(old);
- return 1;
- }
- /* Now go copy */
- count = 0;
- while((ch = fgetc(old)) != EOF) {
- fputc(ch,new);
- if(!(++count)) /* be polite to other users */
- pwait(NULL);
- }
- fclose(old);
- fclose(new);
- return 0;
- }
- #endif /*ALLCMD*/
-
- /*this is also called from the remote-server for the 'exit' command - WG7J*/
- void
- where_outta_here(resetme)
- int resetme;
- {
- time_t StopTime;
- FILE *fp;
- char *inbuf,*intmp;
-
- /* Execute sequence of commands taken from file "~/onexit.nos" */
- /* From iw0cnb */
- if((fp = fopen(Onexit,READ_TEXT)) != NULLFILE){
- inbuf = mallocw(BUFSIZ);
- intmp = mallocw(BUFSIZ);
- while(fgets(inbuf,BUFSIZ,fp) != NULLCHAR){
- strcpy(intmp,inbuf);
- if(Verbose){
- tprintf("%s",intmp);
- rflush();
- }
- if(cmdparse(Cmds,inbuf,NULL) != 0){
- tprintf("input line: %s",intmp);
- }
- }
- fclose(fp);
- free(inbuf);
- free(intmp);
- }
- StopTime = time(&StopTime);
- main_exit = TRUE; /* let everyone know we're out of here */
- reset_all();
- if(Dfile_updater != NULLPROC)
- alert(Dfile_updater,0); /* don't wait for timeout */
- pause(3000); /* Let it finish */
- #ifdef TRACE
- shuttrace();
- #endif
- log(-1,"NOS was stopped");
- if(Logfp){
- fclose(Logfp);
- Logfp = NULLFILE;
- }
- #ifdef UNIX
- detach_all_asy(); /* make sure everything is unlocked */
- pwait(NULL);
- #endif
- iostop();
- if(resetme)
- #ifdef UNIX
- {
- if (fork() == 0)
- abort();
- execvp(origargv[0], origargv); /* re-run NOS */
- }
- #else
- sysreset();
- #endif
- exit(0);
- }
-
- #if 0
- extern struct proc *Aproc;
- #endif
-
- int
- doexit(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- time_t nowtime, elapsedtime;
- unsigned int days,hrs,mins,secs;
-
- #if 0 /* you can't have 2 at's at the same time?? */
- if(Curproc == Aproc) /* From the AT command */
- #endif
- if (strnicmp(Curproc->name, "at ", 3) == 0)
- where_outta_here(0);
-
- if(Curproc->input == Command->input) { /* From keyboard */
- Command->ttystate.edit = Command->ttystate.echo = 0;
- if(toupper(keywait("Are you sure? ",0))=='Y') {
- nowtime = time(&nowtime); /* current time */
- elapsedtime = nowtime - StartTime; /* nos elapsed time */
- secs = elapsedtime % 60;
- elapsedtime = elapsedtime / 60;
- mins = elapsedtime % 60;
- elapsedtime = elapsedtime / 60;
- hrs = elapsedtime % 24;
- elapsedtime = elapsedtime / 24;
- days = elapsedtime;
- tprintf("NOS Exiting - Runtime => %u days:%02u hours:%02u minutes:%02u seconds.\n",days,hrs,mins,secs);
- where_outta_here(0); /*No reset!*/
- }
- Command->ttystate.edit = Command->ttystate.echo = 1;
- return 0;
- }
- /* Anything else; probably mailbox-sysop */
- return -2;
- }
-
- extern char Chostname[];
-
- int
- dohostname(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- #ifdef CONVERS
- char *cp;
- #endif
-
- if(argc < 2)
- tprintf("%s\n",Hostname);
- else {
- struct iface *ifp;
- char *name;
-
- if((ifp = if_lookup(argv[1])) != NULLIF){
- if((name = resolve_a(ifp->addr, FALSE)) == NULLCHAR){
- tprintf("Interface address not resolved\n");
- return 1;
- } else {
- if(Hostname != NULLCHAR)
- free(Hostname);
- Hostname = name;
- tprintf("Hostname set to %s\n", name );
- }
- } else {
- if(Hostname != NULLCHAR)
- free(Hostname);
- Hostname = strdup(argv[1]);
- /* Remove trailing dot */
- if(Hostname[strlen(Hostname)] == '.')
- Hostname[strlen(Hostname)] = '.';
- }
- #ifdef CONVERS
- /* If convers hostname not set yet, set it to first 10 chars
- * of the hostname. If there are '.' from the right, cut off
- * before that. - WG7J
- */
- if(Chostname[0] == '\0') {
- strncpy(Chostname,Hostname,CNAMELEN);
- if((cp = strrchr(Chostname,'.')) != NULLCHAR)
- *cp = '\0';
- }
- #endif
- }
- return 0;
- }
-
- int
- dolog(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- static char *logname;
-
- if(argc < 2){
- if(Logfp)
- tprintf("Logging to %s\n",logname);
- else
- tprintf("Logging off\n");
- return 0;
- }
- if(Logfp){
- log(-1,"NOS log closed");
- fclose(Logfp);
- Logfp = NULLFILE;
- free(logname);
- logname = NULLCHAR;
- }
- if(strcmp(argv[1],"stop") != 0){
- logname = strdup(argv[1]);
- Logfp = fopen(logname,APPEND_TEXT);
- log(-1,"NOS v%s was started at %s", Version, ctime(&StartTime));
- #ifdef MSDOS
- log(-1,NosLoadInfo, _CS, _DS);
- #endif
- }
- return 0;
- }
- int
- dohelp(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- register struct cmds *cmdp;
- int i;
- char buf[66];
-
- tprintf("Main commands:\n");
- memset(buf,' ',sizeof(buf));
- buf[64] = '\n';
- buf[65] = '\0';
- for(i=0,cmdp = Cmds;cmdp->name != NULL;cmdp++,i = (i+1)%4){
- strncpy(&buf[i*16],cmdp->name,strlen(cmdp->name));
- if(i == 3){
- tprintf(buf);
- memset(buf,' ',sizeof(buf));
- buf[64] = '\n';
- buf[65] = '\0';
- }
- }
- if(i != 0)
- tprintf(buf);
- return 0;
- }
-
- /* Attach an interface
- * Syntax: attach <hw type> <I/O address> <vector> <mode> <label> <bufsize> [<speed>]
- */
- int
- doattach(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- return subcmd(Attab,argc,argv,p);
- }
- /* Manipulate I/O device parameters */
- int
- doparam(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- int param,set;
- int32 val;
- register struct iface *ifp;
-
- if((ifp = if_lookup(argv[1])) == NULLIF){
- tprintf(Badinterface,argv[1]);
- return 1;
- }
- if(ifp->ioctl == NULL){
- tprintf("Not supported\n");
- return 1;
- }
- if(argc < 3){
- for(param=1;param<=16;param++){
- val = (*ifp->ioctl)(ifp,param,FALSE,0L);
- if(val != -1)
- tprintf("%s: %ld\n",parmname(param),val);
- }
- return 0;
- }
- param = devparam(argv[2]);
- if(param == -1){
- tprintf("Unknown parameter %s\n",argv[2]);
- return 1;
- }
- if(argc < 4){
- set = FALSE;
- val = 0L;
- } else {
- set = TRUE;
- val = atol(argv[3]);
- }
- val = (*ifp->ioctl)(ifp,param,set,val);
- if(val == -1){
- tprintf("Parameter %s not supported\n",argv[2]);
- } else {
- tprintf("%s: %ld\n",parmname(param),val);
- }
- return 0;
- }
-
- /* Display or set IP interface control flags */
- int
- domode(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- register struct iface *ifp;
-
- if((ifp = if_lookup(argv[1])) == NULLIF){
- tprintf(Badinterface,argv[1]);
- return 1;
- }
- if(argc < 3){
- tprintf("%s: %s\n",ifp->name,
- (ifp->flags & CONNECT_MODE) ? "VC mode" : "Datagram mode");
- return 0;
- }
- switch(argv[2][0]){
- case 'v':
- case 'c':
- case 'V':
- case 'C':
- ifp->flags |= CONNECT_MODE;
- break;
- case 'd':
- case 'D':
- ifp->flags &= ~CONNECT_MODE;
- break;
- default:
- tprintf("Usage: %s [vc | datagram]\n",argv[0]);
- return 1;
- }
- return 0;
- }
-
- #if (!defined(MSDOS) || defined(ESCAPE))
- int
- doescape(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- if(argc < 2)
- tprintf("0x%x\n",Escape);
- else
- Escape = *argv[1];
- return 0;
- }
- #endif MSDOS
- /* Generate system command packet. Synopsis:
- * remote [-p port#] [-k key] [-a hostname] <hostname> reset|exit|kickme
- */
- int
- doremote(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct sockaddr_in fsock;
- int s,c;
- char *data,x;
- int16 port,len;
- char *key = NULLCHAR;
- int klen;
- int32 addr = 0;
- char *cmd,*host;
-
- port = IPPORT_REMOTE; /* Set default */
- optind = 1; /* reinit getopt() */
- #ifdef __GNUC__
- klen = 0; /* defeat spurious "uninitialized" warning */
- #endif
- while((c = getopt(argc,argv,"a:p:k:s:")) != EOF){
- switch(c){
- case 'a':
- if((addr = resolve(optarg)) == 0){
- tprintf(Badhost,optarg);
- return -1;
- }
- break;
- case 'p':
- port = atoi(optarg);
- break;
- case 'k':
- key = optarg;
- klen = strlen(key);
- break;
- case 's':
- Rempass = strdup(optarg);
- return 0; /* Only set local password */
- }
- }
- if(optind > argc - 2){
- tprintf("Insufficient args\n");
- return -1;
- }
- host = argv[optind++];
- cmd = argv[optind];
- if((s = socket(AF_INET,SOCK_DGRAM,0)) == -1){
- tprintf("socket failed\n");
- return 1;
- }
- len = 1;
- /* Did the user include a password or kickme target? */
- if(addr != 0 && cmd[0] == 'k')
- len += sizeof(int32);
-
- if(key != NULLCHAR && (cmd[0] == 'r' || cmd[0] == 'e'))
- len += klen;
-
- if(len == 1)
- data = &x;
- else
- data = mallocw((size_t)len);
-
- fsock.sin_family = AF_INET;
- if((fsock.sin_addr.s_addr = resolve(host)) == 0){
- tprintf(Badhost,host);
- goto cleanup;
- }
- fsock.sin_port = port;
-
- switch(cmd[0]){
- case 'r':
- data[0] = SYS_RESET;
- if(key != NULLCHAR)
- strncpy(&data[1],key,(size_t)klen);
- break;
- case 'e':
- data[0] = SYS_EXIT;
- if(key != NULLCHAR)
- strncpy(&data[1],key,(size_t)klen);
- break;
- case 'k':
- data[0] = KICK_ME;
- if(addr != 0)
- put32(&data[1],addr);
- break;
- default:
- tprintf("Unknown command %s\n",cmd);
- goto cleanup;
- }
- /* Form the command packet and send it */
- if(sendto(s,data,len,0,(char *)&fsock,sizeof(fsock)) == -1){
- tprintf("sendto failed: %s\n",sys_errlist[errno]);
- goto cleanup;
- }
- cleanup:
- if(data != &x)
- free(data);
- close_s(s);
- return 0;
- }
-
- #if (defined(ALLCMD) || defined(ALLSESSIONS))
- int
- morecmd(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct session *sp;
- FILE *fp;
- char buf[81],fname[128];
- int row;
- int usesession = 0;
-
- /* Use a session if this comes from console - WG7J*/
- #ifdef __GNUC__
- row = 0; /* defeat uninitialized warnings */
- sp = 0;
- #endif
- if(Curproc->input == Command->input) {
- usesession = 1;
- if((sp = newsession(argv[1],MORE,0)) == NULLSESSION){
- return 1;
- }
- /* Put tty into raw mode so single-char responses will work */
- sp->ttystate.echo = sp->ttystate.edit = 0;
- row = Numrows - 1;
- }
-
- strcpy(fname,make_fname(Command->curdirs->dir,argv[1]));
- if((fp = fopen(fname,READ_TEXT)) == NULLFILE){
- tprintf(NoRead,fname,sys_errlist[errno]);
- if(usesession) {
- keywait(NULLCHAR,1);
- freesession(sp);
- }
- return 1;
- }
- while(fgets(buf,sizeof(buf),fp),!feof(fp)){
- if((argc < 3) || (strstr(buf,argv[2])!=NULLCHAR)) {
- tprintf("%s",buf);
- if(usesession) {
- if(row > 0 && --row == 0){
- row = keywait("--More--",0);
- switch(row){
- case -1:
- case 'q':
- case 'Q':
- goto done;
- case '\n':
- case '\r':
- row = 1;
- break;
- case ' ':
- default:
- row = Numrows - 1;
- }
- }
- }
- }
- }
- done: fclose(fp);
- if(usesession) {
- keywait(NULLCHAR,1);
- freesession(sp);
- }
- return 0;
- }
-
- int
- domore(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- char **pargv;
- int i;
-
- if(Curproc->input == Command->input) {
- /* Make private copy of argv and args,
- * spawn off subprocess and return.
- */
- pargv = (char **)callocw((size_t)argc,sizeof(char *));
- for(i=0;i<argc;i++)
- pargv[i] = strdup(argv[i]);
- newproc("more",512,(void (*)__ARGS((int,void *,void *)))morecmd,argc,(void *)pargv,p,1);
- } else
- morecmd(argc,argv,p);
- return 0;
- }
-
- #endif
-
- #ifdef ALLCMD
- int
- dotail(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- register int handle, i;
- register unsigned line = 0, rdsize = 2000;
- long length;
- char *buffer;
-
- buffer = callocw(2000, sizeof (char));
-
- if ((handle = open (argv[1], O_BINARY | O_RDONLY)) == -1) {
- tprintf(NoRead,argv[1],sys_errlist[errno]);
- free(buffer);
- return -1;
- }
- length = filelength(handle);
-
- if (length > 2000) {
- length -= 2000;
- } else {
- rdsize = (int) length;
- length = 0;
- }
-
- lseek (handle, length, SEEK_SET);
- if (read (handle, buffer, rdsize) == -1) {
- tprintf(NoRead,argv[1],sys_errlist[errno]);
- close(handle);
- free(buffer);
- return -1;
- }
-
- for (i = rdsize - 1; i > 0; i--) {
- if (buffer[i] == '\n')
- line++;
- if (line == 18)
- break;
- }
- for (; i < rdsize; i++)
- tputc(buffer[i]);
-
- tprintf("\n");
- close(handle);
- free(buffer);
- return 0;
- }
- #endif /*ALLCMD*/
-
- /* No-op command */
- int
- donothing(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- return 0;
- }
-
- static int SendError = 1;
-
- int doerror(int argc,char *argv[],void *p) {
- return setbool(&SendError,"Mail errors",argc,argv);
- }
-
- /* Mail a system message to the sysop - WG7J */
- void
- mail_error(char *fmt, ...)
- {
- FILE *wrk,*txt;
- va_list ap;
- char *cp;
- long t,msgid;
- char fn[128];
-
- if(!SendError)
- return;
-
- /* Get current time */
- time(&t);
-
- /* get the message id for this message */
- msgid = get_msgid();
-
- /* Create the smtp work file */
- sprintf(fn,"%s/%ld.wrk",Mailqdir,msgid);
- if((wrk = fopen(fn,"w")) == NULL)
- return;
-
- /* Create the smtp text file */
- sprintf(fn,"%s/%ld.txt",Mailqdir,msgid);
- if((txt = fopen(fn,"w")) == NULL) {
- fclose(wrk);
- return;
- }
-
- /* Fill in the work file */
- fprintf(wrk,"%s\nMAILER-DAEMON@%s\nsysop@%s",Hostname,Hostname,Hostname);
- fclose(wrk);
-
- /* Fill in the text file headers */
- fprintf(txt,"%s%s",Hdrs[DATE],ptime(&t));
- fprintf(txt,"%s<%ld@%s>\n",Hdrs[MSGID],msgid,Hostname);
- fprintf(txt,"%sMAILER-DAEMON@%s\n",Hdrs[FROM],Hostname);
- fprintf(txt,"%ssysop@%s\n",Hdrs[TO],Hostname);
- fprintf(txt,"%sSystem message\n\n",Hdrs[SUBJECT]);
-
- /* Print the text body */
- cp = ctime(&t);
- fprintf(txt,"On %s",cp);
- va_start(ap,fmt);
- vfprintf(txt,fmt,ap);
- va_end(ap);
- fprintf(txt,"\n");
- fclose(txt);
-
- /* Now kick the smtp server */
- smtptick(NULL);
- }
-
- /* Log messages of the form
- * Tue Jan 31 00:00:00 1987 44.64.0.7:1003 open FTP
- */
- #if defined(ANSIPROTO)
- void
- log(int s,char *fmt, ...)
- {
- va_list ap;
- char *cp;
- long t;
- int i;
- struct sockaddr fsocket;
- #ifdef MSDOS
- int fd;
- #endif
-
- if(Logfp == NULLFILE)
- return;
-
- time(&t);
- cp = ctime(&t);
- rip(cp);
- i = SOCKSIZE;
- fprintf(Logfp,"%s",cp);
- if(getpeername(s,(char *)&fsocket,&i) != -1)
- fprintf(Logfp," %s",psocket(&fsocket));
-
- fprintf(Logfp," - ");
- va_start(ap,fmt);
- vfprintf(Logfp,fmt,ap);
- va_end(ap);
- fprintf(Logfp,"\n");
- fflush(Logfp);
- #ifdef MSDOS
- /* MS-DOS doesn't really flush files until they're closed */
- fd = fileno(Logfp);
- if((fd = dup(fd)) != -1)
- close(fd);
- #endif
-
- }
- #else
- /*VARARGS2*/
- void
- log(s,fmt,arg1,arg2,arg3,arg4,arg5)
- int s;
- char *fmt;
- int arg1,arg2,arg3,arg4,arg5;
- {
- char *cp;
- long t;
- int fd,i;
- struct sockaddr fsocket;
-
- if(Logfp == NULLFILE)
- return;
- time(&t);
- cp = ctime(&t);
- rip(cp);
- i = SOCKSIZE;
- fprintf(Logfp,"%s",cp);
- if(getpeername(s,(char *)&fsocket,&i) != -1)
- fprintf(Logfp," %s",psocket(&fsocket));
-
- fprintf(Logfp," - ");
- fprintf(Logfp,fmt,arg1,arg2,arg3,arg4,arg5);
- fprintf(Logfp,"\n");
- fflush(Logfp);
- #ifdef MSDOS
- /* MS-DOS doesn't really flush files until they're closed */
- fd = fileno(Logfp);
- if((fd = dup(fd)) != -1)
- close(fd);
- #endif
- }
- #endif
-
- int
- dosource(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- int linenum = 0;
- char *inbuf,*intmp;
- FILE *fp;
-
- /* Read command source file */
- if((fp = fopen(argv[1],READ_TEXT)) == NULLFILE){
- tprintf(NoRead,argv[1],sys_errlist[errno]);
- return 1;
- }
-
- inbuf = malloc(BUFSIZ);
- intmp = malloc(BUFSIZ);
- while(fgets(inbuf,BUFSIZ,fp) != NULLCHAR){
- strcpy(intmp,inbuf);
- linenum++;
- if(Verbose)
- tprintf("%s",intmp);
- if(cmdparse(Cmds,inbuf,NULL) != 0){
- tprintf("*** file \"%s\", line %d: %s\n",
- argv[1],linenum,intmp);
- }
- }
- fclose(fp);
- free(inbuf);
- free(intmp);
- return 0;
- }
-
- /* if unattended mode is set - restrict ax25, telnet and maybe other sessions */
- int
- doattended(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- return setbool(&Attended,"Attended flag",argc,argv);
- }
-
- /* if ThirdParty is not set - restrict the mailbox (S)end command to local only */
- int
- dothirdparty(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- return setbool(&ThirdParty,"Third-Party mail flag",argc,argv);
- }
-
- #ifdef ALLCMD
- int
- domdump(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- unsigned int i;
- char * addr;
- unsigned int len = 8 * 16; /* default is 8 lines of hex dump */
-
- if(argc < 2 || argc > 3) {
- tprintf("Usage:- dump <hex-address | .> [decimal-range] \n");
- return 0;
- }
- if(argv[1][0] == '.')
- addr = DumpAddr; /* Use last end address */
- else
- addr = ltop(htol(argv[1])); /* get address of item being dumped */
-
- if(argc == 3) {
- len = atoi(argv[2]);
- len = ((len + 15) >> 4) << 4; /* round up to modulo 16 */
- }
-
- if(len < 1 || len > 256) {
- tprintf("Invalid dump range. Valid is 1 to 256\n");
- return 0;
- }
- #ifdef UNIX
- tprintf(" Main Memory Dump Of Location %lx\n", FP_SEG(addr));
- #else
- tprintf(" Main Memory Dump Of Location %Fp\n", addr);
- #endif
- tprintf("Addr (offset) Hexadecimal Ascii\n");
- tprintf("---- ----------- -----\n\n");
-
- for(i = 0; i < len; i += 16)
- fmtline((int16)i, (char *)(addr + i), 16);
- DumpAddr = (char *)(addr + i); /* update address */
- return 0;
- }
-
- /* Print a buffer up to 16 bytes long in formatted hex with ascii
- * translation, e.g.,
- * 0000: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 0123456789:;<=>?
- */
- static void
- fmtline(addr,buf,len)
- int16 addr;
- char *buf;
- int16 len;
- {
- char line[81];
- register char *aptr,*cptr;
- register char c;
-
- memset(line,' ',sizeof(line));
- ctohex(line,(int16)hibyte(addr));
- ctohex(line+2,(int16)lobyte(addr));
- aptr = &line[6];
- cptr = &line[55];
- while(len-- != 0){
- c = *buf++;
- ctohex(aptr,(int16)uchar(c));
- aptr += 3;
- c &= 0x7f;
- if((c > 0x1f) && (c < 0x7f))
- *cptr++ = c;
- else
- *cptr++ = '.';
- }
- *cptr++ = '\0';
- tprintf("%s\n",line);
- }
- /* Convert byte to two ascii-hex characters */
- static void
- ctohex(buf,c)
- register char *buf;
- register int16 c;
- {
- static char hex[] = "0123456789abcdef";
-
- *buf++ = hex[hinibble(c)];
- *buf = hex[lonibble(c)];
- }
- #endif
-
- int
- dowrite(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- int s;
- struct mbx *m;
-
- if((s = atoi(argv[1])) == 0) { /* must be a name */
- #ifdef MAILBOX
- /* check the mailbox users */
- for(m=Mbox;m;m=m->next){
- if(!strcmp(m->name,argv[1]))
- break;
- }
- if(!m)
- return 0;
- s = m->user;
- #else
- return 0;
- #endif
- }
- usprintf(s,"*** Msg from SYSOP: %s\n",argv[2]);
- usflush(s);
-
- return 0;
- }
-
- #ifdef MAILBOX
- /* write a message to all nodeshell users
- * argv[1] is the message.
- */
- int
- dowriteall(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- register struct mbx *m;
-
- for(m=Mbox;m;m=m->next){
- usprintf(m->user,"*** Msg from SYSOP: %s\n",argv[1]);
- usflush(m->user);
- }
- return 0;
- }
- #endif
-
-
- int
- dostatus(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- time_t nowtime, elapsedtime;
- unsigned int days,hrs,mins,secs;
-
- nowtime = time(&nowtime); /* current time */
- elapsedtime = nowtime - StartTime; /* nos elapsed time */
-
- tprintf(Nosversion,Version);
- tputs(Version2);
- tprintf("Tty: %d rows, %d columns\n",Numrows,Numcols);
-
- #ifdef MSDOS
- tprintf(NosLoadInfo, _CS, _DS);
- #endif
- tprintf("\nThe system time is %s", ctime(&nowtime));
- tprintf("NOS was started on %s\n", ctime(&StartTime));
- secs = elapsedtime % 60;
- elapsedtime = elapsedtime / 60;
- mins = elapsedtime % 60;
- elapsedtime = elapsedtime / 60;
- hrs = elapsedtime % 24;
- elapsedtime = elapsedtime / 24;
- days = elapsedtime;
- tprintf("Elapsed time => %u days:%02u hours:%02u minutes:%02u seconds.\n\n",days,hrs,mins,secs);
- #ifdef ALLCMD
- tprintf("The station is currently %sttended.\n", Attended ? "A" : "Una");
- tprintf("The 'Message Of The Day' is ");
- if(Motd != NULLCHAR)
- tprintf("\n%s",Motd);
- else
- tprintf("not set!\n");
- #endif
- #ifdef __TURBOC__
- dofstat(); /* print status of open files */
- #endif
- return 0;
- }
-
- #ifdef ALLCMD
- int
- domotd(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- if(argc > 2) {
- tprintf("Usage: motd \"<your message>\"\n");
- return 1;
- }
-
- if(argc < 2) {
- if(Motd != NULLCHAR)
- tprintf("%s",Motd);
- } else {
- if(Motd != NULLCHAR){
- free(Motd);
- Motd = NULLCHAR; /* reset the pointer */
- }
-
- if(!strlen(argv[1]))
- return 0; /* clearing the buffer */
-
- Motd = mallocw(strlen(argv[1])+5); /* allow for the EOL char etc */
- strcpy(Motd, argv[1]);
- strcat(Motd, "\n"); /* add the EOL char */
- }
- return 0;
- }
- #endif /*ALLCMD*/
-
- #ifdef __TURBOC__
- /*
- * Fstat utility code.
- * Converted to go into NOS by Kelvin Hill - G1EMM April 9, 1990
- */
-
- extern unsigned char _osmajor;
-
- static char *localcopy(char far *);
- static char *progname(unsigned int);
-
- int
- dofstat()
- {
- union REGS regs;
- struct SREGS segregs;
- char far *pfiletab, far * pnext, far * fp;
- char far *name, file[13], far * plist, far * entry;
- char ownername[9], ownerext[5];
- int nfiles, i, j, numhandles, entrylen;
- unsigned int access, devinfo, progpsp;
- long length, offset;
- int heading = 0;
-
- regs.h.ah = 0x52; /* DOS list of lists */
- intdosx(®s, ®s, &segregs);
-
- /* make a pointer to start of master list */
- plist = (char far *) MK_FP(segregs.es, regs.x.bx);
-
- /* pointer to start of file table */
- pfiletab = (char far *) MK_FP(*(int far *) (plist + 6), *(int far *) (plist + 4));
-
- switch (_osmajor) {
- case 2:
- entrylen = 40; /* DOS 2.x */
- break;
- case 3:
- entrylen = 53; /* DOS 3.x */
- break;
- case 4:
- case 5: /* DOS 5.x - like dos 4.x */
- case 6: /* and NOW DOS 6.0 also */
- entrylen = 59; /* DOS 4.x - I do not know what is in the
- * extra 6 bytes */
- break;
- default:
- /*
- tprintf("Sorry, cannot handle this version of MS-DOS");
- */
- return 1;
- }
-
- for (;;) {
- /* pointer to next file table */
- pnext = (char far *) MK_FP(*(int far *) (pfiletab + 2), *(int far *) (pfiletab + 0));
- nfiles = *(int far *) (pfiletab + 4);
- #ifdef DEBUG
- tprintf("\nFile table at %Fp entries for %d files\n", pfiletab, nfiles);
- #endif
- for (i = 0; i < nfiles; i++) {
-
- /*
- * cycle through all files, quit when we reach an
- * unused entry
- */
- entry = pfiletab + 6 + (i * entrylen);
- if (_osmajor >= 3) {
- name = entry + 32;
- strncpy(file, localcopy(name), 11);
- file[11] = '\0';
- numhandles = *(int far *) (entry + 0);
- access = (int) *(char far *) (entry + 2);
- length = *(long far *) (entry + 17);
- offset = *(long far *) (entry + 21);
- devinfo = *(int far *) (entry + 5);
- progpsp = *(int far *) (entry + 49);
- } else {
- name = entry + 4;
- strncpy(file, localcopy(name), 11);
- file[11] = '\0';
- numhandles = (int) *(char far *) (entry + 0);
- access = (int) *(char far *) (entry + 1);
- length = *(long far *) (entry + 19);
- offset = *(long far *) (entry + 36);
- devinfo = (int) *(char far *) (entry + 27);
- }
- if ((strlen(file) > 0) && (numhandles > 0) && !(devinfo & 0x80)) {
- if(!heading) {
- tprintf("\n");
- tprintf(" Table of Open Files.\n");
- tprintf(" --------------------\n");
- tprintf("Name length offset hnd acc PSP device type/owner\n");
- tprintf("---- ------ ------ --- --- --- -----------------\n");
- heading++; /* header now printed */
- }
- tprintf("%8.8s.%3.3s %8ld %8ld %2d ",
- file, &file[8], length, offset, numhandles);
- switch (access) {
- case 0:
- tprintf("r ");
- break;
- case 1:
- tprintf("w ");
- break;
- case 2:
- tprintf("rw ");
- break;
- default:
- tprintf(" ");
- }
- if (_osmajor >= 3)
- tprintf("%04X ", progpsp);
- else
- tprintf("---- ");
- tprintf("drive %c: ", 'A' + (devinfo & 0x1F));
- if (devinfo & 0x8000)
- tprintf("(network) ");
- if (_osmajor >= 3) {
- /*
- * only DOS 3+ can find out
- * the name of the program
- */
- fnsplit(progname(progpsp), NULL, NULL, ownername, ownerext);
- tprintf(" [%s%s]\n", strlwr(ownername), strlwr(ownerext));
- } else {
- tprintf("\n");
- }
- }
- if (strlen(file) == 0)
- return 0;
- }
- pfiletab = pnext;
- }
- }
-
- /* Make a copy of a string pointed to by a far pointer */
- static char *
- localcopy(s)
- char far *s;
- {
- static char localstring[256];
- char far *p = s;
- char *l = localstring;
- int i = 0;
-
- while (*p != NULL && i++ < 255) {
- *l++ = *p++;
- }
-
- *l = '\0';
-
- return (localstring);
- }
-
- /*
- * Return a near pointer to a character string with the full path name of the
- * program whose PSP is given in the argument. If the argument is invalid,
- * this may return gibberish but I don't know how to tell Offset 0x2C in the
- * PSP in the segment address of the environment of a program. Beyond the
- * last environment string is a null marker, a word count (usually 1), then
- * the full pathname of the owner of the environment This only works for DOS
- * 3+
- */
- static char *
- progname(pid)
- unsigned int pid;
- {
- unsigned far *envsegptr; /* Pointer to seg address of
- * environment */
- char far *envptr; /* Pointer to pid's environment */
- unsigned far *envsizeptr; /* Pointer to environment size */
- unsigned envsize;/* Size of pid's environment */
- unsigned ppid; /* Parent psp address */
-
- /* find the parent process psp at offset 0x16 of the psp */
- ppid = *(unsigned far *) MK_FP(pid, 0x16);
-
- /* find the environment at offset 2Ch of the psp */
- envsegptr = (unsigned far *) MK_FP(pid, 0x2C);
- envptr = (char far *) MK_FP(*envsegptr, 0);
-
- /*
- * Make a pointer that contains the size of the environment block.
- * Must point back one paragraph (to the environments MCB plus three
- * bytes forward (to the MCB block size field).
- */
- envsizeptr = (unsigned far *) MK_FP(*envsegptr - 1, 0x3);
- envsize = *envsizeptr * 16; /* x 16 turns it into bytes */
-
- while (envsize > 0) {
- /* search for end of environment block, or NULL */
- while (--envsize && *envptr++);
-
- /*
- * Now check for another NULL immediately following the first
- * one located and a word count of 0001 following that.
- */
- if (!*envptr && *(unsigned far *) (envptr + 1) == 0x1) {
- envptr += 3;
- break;
- }
- }
-
- if (envsize > 0) {
- /* Owner name found - return it */
- return (localcopy(envptr));
- } else {
- if (pid == ppid) {
- /*
- * command.com doesn't leave it's name around, but if
- * pid = ppid then we know we have a shell
- */
- return ("-shell-");
- } else {
- return ("unknown");
- }
- }
- }
- #endif /*__TURBOC__*/
-
- int
- doprompt(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- return setbool(&DosPrompt,"prompt",argc,argv);
- }
-
- /* Command history, see also pc.c - WG7J */
- void logcmd(char *cmd) {
- struct hist *new;
- char *cp;
-
- if(!Maxhistory) /* don't keep history */
- return;
-
- /* Get rid of \n; this is also done in cmdparse().
- * We HAVE to do this here, since the string is NOT null-terminated when
- * it comes from recv_mbuf() !!!! rip() makes it nullterminated.
- */
- rip(cmd);
- cp = cmd;
- while(*cp == ' ' || *cp == '\t')
- cp++;
- if(!*cp) /* Empty command */
- return;
-
- if(Histrysize < Maxhistory) { /* Add new one */
- Histrysize++;
- if(!Histry) { /* Empty list */
- /* Initialize circular linked list */
- Histry = mallocw(sizeof(struct hist));
- Histry->next = Histry->prev = Histry;
- } else {
- new = mallocw(sizeof(struct hist));
- /* Now link it in */
- Histry->next->prev = new;
- new->next = Histry->next;
- new->prev = Histry;
- Histry->next = new;
- Histry = new;
- }
- } else {
- /* Maximum number stored already, use the oldest entry */
- Histry = Histry->next;
- free(Histry->cmd);
- }
- Histry->cmd = strdup(cp);
- }
-
- int
- dohistory(int argc,char *argv[],void *p) {
- struct hist *h;
- int num;
-
- if(argc > 1) {
- Maxhistory = atoi(argv[1]);
- return 0;
- }
- tprintf("Max recall %d\n",Maxhistory);
- if((h = Histry) == NULL)
- return 0;
- num = 0;
- do {
- tprintf("%.2d: %s\n",num++,h->cmd);
- h = h->prev;
- } while(h != Histry);
- return 0;
- }
-
- #ifndef UNIX
-
- /* This adds some additional checks to the fopen()
- * in the Borland C++ Run Time Library.
- * It fixes problem with users trying to open system devices like
- * CON, AUX etc and hang a system.
- * WG7J, 930205
- */
- #undef fopen
- FILE _FAR *_Cdecl fopen(const char _FAR *__path, const char _FAR *__mode);
-
- static char *InvalidName[] = {
- "NUL",
- "CON",
- "AUX",
- "PRN",
- "LPT1",
- "LPT2",
- "LPT3",
- "COM1",
- "COM2",
- "COM3",
- "COM4",
- "MOUSE$",
- "CLOCK$",
- NULLCHAR,
- };
-
- FILE *newfopen (const char *filename, const char *type) {
- int i;
-
- for(i=0;InvalidName[i] != NULLCHAR;i++)
- if(stricmp(InvalidName[i],filename) == 0)
- return NULL;
-
- return fopen (filename, type);
- }
-
- #endif
-
- #if defined(__TURBOC__) && !defined(__BORLANDC__)
- /* N5KNX: TurboC 2.0 lacks _setcursortype(), which we supply here for dorepeat */
- void _setcursortype(int style)
- {
- /* From TurboC++ conio.h: */
- #define _NOCURSOR 0
- #define _SOLIDCURSOR 1
- #define _NORMALCURSOR 2
-
- /* Int 0x10 reg cx codes: */
- #define STD_CURSOR 0x0607
- #define BLK_CURSOR 0x0006
- #define NO_CURSOR 0x2607
-
- union REGS regs;
-
- if (style == _NOCURSOR) regs.x.cx = NO_CURSOR;
- else if (style == _SOLIDCURSOR) regs.x.cx = BLK_CURSOR;
- else if (style == _NORMALCURSOR) regs.x.cx = STD_CURSOR;
- else return;
- regs.x.ax = 0x0100; /* set cursor */
- int86(0x10, ®s, ®s);
- }
- #endif
-
- /* Repeat a command - taken from 930104 KA9Q NOS
- WA3DSP 1/93
- */
- int
- dorepeat(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- int32 interval;
- int ret;
- struct session *sp;
-
- if(isdigit(argv[1][0])){
- interval = atol(argv[1]);
- argc--;
- argv++;
- } else {
- interval = MSPTICK;
- }
- if((sp = newsession(argv[2],REPEAT,1)) == NULLSESSION){
- tprintf("Too many sessions\n");
- return 1;
- }
- _setcursortype(_NOCURSOR);
- while(sp==Current){
- /* clrscr(); */
- /* gotoxy seems to work better - turn cursor off?? */
- gotoxy(1,1);
- ret = subcmd(Cmds,argc,argv,p);
- if(ret != 0 || pause(interval) == -1)
- break;
- }
- _setcursortype(_NORMALCURSOR);
- freesession(sp);
- return 0;
- }
-
-